﻿#region Header

// Majesty of Omega - The next evolution of macro management space strategy
// 
// Copyright 2007-2009 André Claaßen
// 
// This file is protected by the terms and conditions of the
// Microsoft Community License (Ms-CL 1.1), a copy of which should
// have been distributed along with this software. If not,
// you may find the license information at the following URL:
// 
// http://www.microsoft.com/resources/sharedsource/licensingbasics/communitylicense.mspx

#endregion

#region

using System;
using System.Runtime.Serialization;
using DesignByContract;
using Majesty_of_Omega.Config;
using Majesty_of_Omega.Model.Research;
using Majesty_of_Omega.Model.Report;

#endregion

namespace Majesty_of_Omega.Model.Game
{
    /// <summary>
    /// This class represents a player of the game. A player could be a human player or an AI.
    /// </summary>
    [Serializable]
    public class Player : IDeserializationCallback, IEquatable<Player>
    {
        /// <summary>
        /// Name of the Empire
        /// </summary>
        private readonly string _empireName;

        /// <summary>
        /// Name of the race for deserialization
        /// </summary>
        private readonly string _raceName;


        /// <summary>
        /// The SituationReport (<see cref="Majesty_of_Omega.Model.Report.SitReport" />) of the game
        /// </summary>
        private SitReport _sitReport = new SitReport();

        /// <summary>
        /// Gets or sets the SituationReport (<see cref="Majesty_of_Omega.Model.Report.SitReport" />) of the game
        /// </summary>
        /// <value>The report.</value>
        public SitReport SitReport
        {
            get { return _sitReport; }
            set { _sitReport = value; }
        }

        /// <summary>
        /// Selected race for this player
        /// </summary>
        [NonSerialized] 
        private RaceModifiersRace _race;

        /// <summary>
        /// The <see cref="ResearchManager" /> manages the discovery of new technology and the distribution of research points
        /// </summary>
        private readonly ResearchManager _researchManager = new ResearchManager();

        /// <summary>
        /// The <see cref="ResearchManager" /> manages the discovery of new technology and the distribution of research points
        /// </summary>
        public ResearchManager ResearchManager
        {
            get { return _researchManager; }
        }

        /// <summary>
        /// Constructs a new plaeyer
        /// </summary>
        /// <param name="empireName">Name of the Empire</param>
        /// <param name="race">race</param>
        public Player(string empireName, RaceModifiersRace race)
        {
            Require.IsFalse(string.IsNullOrEmpty(empireName));
            Require.IsNotNull(race);

            _empireName = empireName;
            _race = race;
            _raceName = race.Name;
        }

        /// <summary>
        /// Selected race for this player
        /// </summary>
        public RaceModifiersRace Race
        {
            get { return _race; }
        }

        ///<summary>
        /// Name of the Empire
        ///</summary>
        public string EmpireName
        {
            get { return _empireName; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Player"/> is human.
        /// </summary>
        /// <value><c>true</c> if human; otherwise, <c>false</c>.</value>
        public bool Human { get; set; }

        #region IDeserializationCallback Members

        /// <summary>
        /// Runs when the entire object graph has been deserialized. 
        /// </summary>
        /// <param name="sender">The object that initiated the callback. The functionality for this parameter is not currently implemented.</param>
        public void OnDeserialization(object sender)
        {
            _race = SpreadSheetManager.RaceModifiers.RaceForName(_raceName);
        }

        #endregion

        #region IEquatable<Player> Members

        /// <summary>
        /// Equalses the specified player.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <returns></returns>
        public bool Equals(Player player)
        {
            if (player == null) return false;
            if (!Equals(_empireName, player._empireName)) return false;
            if (!Equals(_raceName, player._raceName)) return false;
            return true;
        }


        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj)) return true;
            return Equals(obj as Player);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            int result = _empireName != null ? _empireName.GetHashCode() : 0;
            result = 29*result + (_raceName != null ? _raceName.GetHashCode() : 0);
            return result;
        }
        #endregion
    }
}